using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Attributes.DomainAttributes;
using Baci.Net.ToolKit.ArcGISProGeoprocessor.Models.Enums;
using System.Collections.Generic;
using System.ComponentModel;

namespace Baci.ArcGIS._SpatialStatisticsTools._AnalyzingPatterns
{
    /// <summary>
    /// <para>Average Nearest Neighbor</para>
    /// <para>Calculates a nearest neighbor index based on the average distance from each feature to its nearest neighboring feature.</para>
    /// <para>根据从每个要素到其最近邻要素的平均距离计算最近邻索引。</para>
    /// </summary>    
    [DisplayName("Average Nearest Neighbor")]
    public class AverageNearestNeighbor : AbstractGPProcess
    {
        /// <summary>
        /// 无参构造
        /// </summary>
        public AverageNearestNeighbor()
        {

        }

        /// <summary>
        /// 有参构造
        /// </summary>
        /// <param name="_Input_Feature_Class">
        /// <para>Input Feature Class</para>
        /// <para>The feature class, typically a point feature class, for which the average nearest neighbor distance will be calculated.</para>
        /// <para>要素类，通常为点要素类，将为其计算平均最近邻距离。</para>
        /// </param>
        /// <param name="_Distance_Method">
        /// <para>Distance Method</para>
        /// <para><xdoc>
        ///   <para>Specifies how distances are calculated from each feature to neighboring features.</para>
        ///   <bulletList>
        ///     <bullet_item>Euclidean—The straight-line distance between two points (as the crow flies)</bullet_item><para/>
        ///     <bullet_item>Manhattan—The distance between two points measured along axes at right angles (city block); calculated by summing the (absolute) difference between the x- and y-coordinates</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定如何计算从每个要素到相邻要素的距离。</para>
        ///   <bulletList>
        ///     <bullet_item>欧几里得 - 两点之间的直线距离（乌鸦飞翔时）</bullet_item><para/>
        ///     <bullet_item>曼哈顿 - 沿直角轴测量的两点之间的距离（城市街区）;通过将 x 坐标和 y 坐标之间的（绝对）差求和计算得出</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// </param>
        public AverageNearestNeighbor(object _Input_Feature_Class, _Distance_Method_value _Distance_Method)
        {
            this._Input_Feature_Class = _Input_Feature_Class;
            this._Distance_Method = _Distance_Method;
        }
        public override string ToolboxName => "Spatial Statistics Tools";

        public override string ToolName => "Average Nearest Neighbor";

        public override string CallName => "stats.AverageNearestNeighbor";

        public override List<string> AcceptEnvironments => ["geographicTransformations", "outputCoordinateSystem", "scratchWorkspace", "workspace"];

        public override object[] ParameterInfo => [_Input_Feature_Class, _Distance_Method.GetGPValue(), _Generate_Report.GetGPValue(), _Area, _NNRatio, _NNZScore, _PValue, _NNExpected, _NNObserved, _Report_File];

        /// <summary>
        /// <para>Input Feature Class</para>
        /// <para>The feature class, typically a point feature class, for which the average nearest neighbor distance will be calculated.</para>
        /// <para>要素类，通常为点要素类，将为其计算平均最近邻距离。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Input Feature Class")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public object _Input_Feature_Class { get; set; }


        /// <summary>
        /// <para>Distance Method</para>
        /// <para><xdoc>
        ///   <para>Specifies how distances are calculated from each feature to neighboring features.</para>
        ///   <bulletList>
        ///     <bullet_item>Euclidean—The straight-line distance between two points (as the crow flies)</bullet_item><para/>
        ///     <bullet_item>Manhattan—The distance between two points measured along axes at right angles (city block); calculated by summing the (absolute) difference between the x- and y-coordinates</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定如何计算从每个要素到相邻要素的距离。</para>
        ///   <bulletList>
        ///     <bullet_item>欧几里得 - 两点之间的直线距离（乌鸦飞翔时）</bullet_item><para/>
        ///     <bullet_item>曼哈顿 - 沿直角轴测量的两点之间的距离（城市街区）;通过将 x 坐标和 y 坐标之间的（绝对）差求和计算得出</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Distance Method")]
        [Description("")]
        [Option(OptionTypeEnum.Must)]
        public _Distance_Method_value _Distance_Method { get; set; }

        public enum _Distance_Method_value
        {
            /// <summary>
            /// <para>Euclidean</para>
            /// <para>Euclidean—The straight-line distance between two points (as the crow flies)</para>
            /// <para>欧几里得 - 两点之间的直线距离（乌鸦飞翔时）</para>
            /// </summary>
            [Description("Euclidean")]
            [GPEnumValue("EUCLIDEAN_DISTANCE")]
            _EUCLIDEAN_DISTANCE,

            /// <summary>
            /// <para>Manhattan</para>
            /// <para>Manhattan—The distance between two points measured along axes at right angles (city block); calculated by summing the (absolute) difference between the x- and y-coordinates</para>
            /// <para>曼哈顿 - 沿直角轴测量的两点之间的距离（城市街区）;通过将 x 坐标和 y 坐标之间的（绝对）差求和计算得出</para>
            /// </summary>
            [Description("Manhattan")]
            [GPEnumValue("MANHATTAN_DISTANCE")]
            _MANHATTAN_DISTANCE,

        }

        /// <summary>
        /// <para>Generate Report</para>
        /// <para><xdoc>
        ///   <para>Specifies whether the tool will create a graphical summary of results.</para>
        ///   <bulletList>
        ///     <bullet_item>Checked—A graphical summary will be created as an HTML file.</bullet_item><para/>
        ///     <bullet_item>Unchecked—No graphical summary will be created. This is the default.</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para><xdoc>
        ///   <para>指定该工具是否将创建结果的图形摘要。</para>
        ///   <bulletList>
        ///     <bullet_item>选中 - 图形摘要将创建为 HTML 文件。</bullet_item><para/>
        ///     <bullet_item>未选中 - 不会创建图形摘要。这是默认设置。</bullet_item><para/>
        ///   </bulletList>
        /// </xdoc></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Generate Report")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public _Generate_Report_value _Generate_Report { get; set; } = _Generate_Report_value._false;

        public enum _Generate_Report_value
        {
            /// <summary>
            /// <para>GENERATE_REPORT</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("GENERATE_REPORT")]
            [GPEnumValue("true")]
            _true,

            /// <summary>
            /// <para>NO_REPORT</para>
            /// <para></para>
            /// <para></para>
            /// </summary>
            [Description("NO_REPORT")]
            [GPEnumValue("false")]
            _false,

        }

        /// <summary>
        /// <para>Area</para>
        /// <para>A numeric value representing the study area size. The default value is the area of the minimum enclosing rectangle that would encompass all features (or all selected features). Units should match those for the Output Coordinate System.</para>
        /// <para>表示研究区域大小的数值。默认值是包含所有要素（或所有选定要素）的最小封闭矩形的面积。单位应与输出坐标系的单位匹配。</para>
        /// <para></para>
        /// </summary>
        [DisplayName("Area")]
        [Description("")]
        [Option(OptionTypeEnum.optional)]
        public double? _Area { get; set; } = null;


        /// <summary>
        /// <para>Nearest Neighbor Index</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Nearest Neighbor Index")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public double _NNRatio { get; set; }


        /// <summary>
        /// <para>z-score</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("z-score")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public double _NNZScore { get; set; }


        /// <summary>
        /// <para>p-value</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("p-value")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public double _PValue { get; set; }


        /// <summary>
        /// <para>Expected Mean Distance</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Expected Mean Distance")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public double _NNExpected { get; set; }


        /// <summary>
        /// <para>Observed Mean Distance</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Observed Mean Distance")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public double _NNObserved { get; set; }


        /// <summary>
        /// <para>Report File</para>
        /// <para></para>
        /// <para></para>
        /// <para></para>
        /// </summary>
        [DisplayName("Report File")]
        [Description("")]
        [Option(OptionTypeEnum.derived)]
        public object _Report_File { get; set; }


        public AverageNearestNeighbor SetEnv(object geographicTransformations = null, object outputCoordinateSystem = null, object scratchWorkspace = null, object workspace = null)
        {
            base.SetEnv(geographicTransformations: geographicTransformations, outputCoordinateSystem: outputCoordinateSystem, scratchWorkspace: scratchWorkspace, workspace: workspace);
            return this;
        }

    }

}